/**
 * Created by 009 on 2017/6/7.
 */
/**
 * Created by 009 on 2017/6/6.
 */
/**
 * Created by fang on 2017/6/5.
 */
/**
 * Created by 009 on 2017/5/26.
 */
//@charset "UTF-8";
(function ($, window, document, undefined) {

    "use strict";

    window = (typeof window != 'undefined' && window.Math == Math)
        ? window
        : (typeof self != 'undefined' && self.Math == Math)
            ? self
            : Function('return this')()
    ;

    $.fn.tablebind = function (tableColumns, tableSettings) {
        //error const
        const
            INVALID_DATA_URL = '无效的配置data url',
            INVALID_ADD_URL  = '无效的配置add url',
            INVALID_UPDATE_URL = '无效的配置update url',
            INVALID_DELETE_URL = '无效的配置delete url';

        var
            settings = ( $.isPlainObject(tableSettings) )
                ? $.extend(true, {}, $.fn.tablebind.settings, tableSettings)
                : $.extend({}, $.fn.tablebind.settings),
            columns = ($.isArray(tableColumns))
                ? tableColumns
                : [],//$.extend([], $.fn.tablebind.columns),
            lengthList = settings.lengthList,
            _lengthList = [],
            $wrapper = ($(this).length === 0)
                ? $('<div></div>')
                : $(this),
            $table_section = $wrapper.children('div:has(table)'),
            key = settings.key,
            _columns = [],
            element = this,
            $element = $(this),
            $toolbar = $(this).find('div[data-section=toolBar]'),
            $table = $table_section.find('table'),
            //$table = $(this).find('table'),
            $view_add = $(this).find('div[data-section=add]'),
            table_id = queryTableId(settings.tableId),
            $view_update = $('.modal[data-section=update][data-table='+table_id+']'),
            $view_delete = $('.modal[data-section=delete][data-table='+table_id+']'),
            //instance = $module.data(moduleNamespace),
            returnedValue,
            module;
        //检查配置
        //checkSetting();

        //$modules = $(this);
        //合并列
        $.each(columns, function (idx,col) {
            col = $.isPlainObject(col)
                ? $.extend(true, {}, $.fn.tablebind.column, col)
                : $.extend({}, $.fn.tablebind.column, {label:idx,name:idx});
            col.index = idx;
            _columns.push(col);
        });

        //检查分页大小列表
        if(!$.isArray(lengthList)) {
            lengthList = $.fn.tablebind.settings.lengthList;
        } else {
            $.each(lengthList, function (idx, length) {
                var len = Number.parseInt(length);
                if(isNaN(len)) return true;
                _lengthList.push(len);
            });
        }
        _lengthList.sort();
        settings.lengthList = lengthList = _lengthList;


        columns = _columns;
        console.info(JSON.stringify(columns));
        //
        $wrapper.data('id', table_id);
        settings.tableId = table_id;

        module = {
            initialize : function () {
                if($table_section.length === 0) {
                    $table_section = $('<div></div>');
                    $wrapper.prepend($table_section);
                    $table_section.data('section', 'table');
                    $table_section.attr('data-section', 'table');

                } else if ($table_section.attr('data-section') != 'table') {
                    $table_section.data('section', 'table');
                    $table_section.attr('data-section', 'table');
                }
                //load tool bar
                if($toolbar.length === 0) {
                    $toolbar = createToolBar();
                    console.info($toolbar);
                    $table_section.prepend($toolbar);
                    $toolbar.find('.ui.calendar').calendar();
                    $toolbar.find('.ui.dropdown').dropdown();
                }
                //load table body
                if($table.length === 0) {
                    $table = createTable();
                    $table_section.append($table);
                    $table.find('.ui.dropdown').dropdown();
                    $table.data('total', 0);
                    $table.data('size', 0);
                } else if($table.find('tfoot').length === 0) {
                    var $footer = createPagingBar();
                    $table.append($footer);
                    //加载分页条
                    module.loadPaging($table, $table.data('total'), 1, $table.data('size'));
                    $table.find('.ui.dropdown').dropdown();
                }
                //load table pag
                //load add view
                if(($view_add.length === 0) && (settings.enableAdd === true)) {
                    $view_add = createAddView();
                    $wrapper.append($view_add);
                    $view_add.find('.ui.calendar').calendar();
                    $view_add.find('.ui.dropdown').dropdown();
                }
                //load update view
                if(($view_update.length === 0) && settings.enableEdit === true) {
                    $view_update = createUpdateView();
                    $('body').append($view_update);
                    $view_update.modal({closable : false});//init
                    $view_update.find('.ui.calendar').calendar();
                    $view_update.find('.ui.dropdown').dropdown();
                }

                //load delete view
                if(($view_delete.length === 0) && settings.enableDelete === true) {
                    $view_delete = createDeleteView();
                    $('body').append($view_delete);
                    $view_delete.modal({
                        onDeny    : function(){
                            return false;
                        },
                        onApprove : function() {
                            return false;
                        }
                    });

                }

                //
                //bind tool bar event
                module.bindEvents.toolbar();
                //bind table row and row tools event
                module.bindEvents.tablerow();
                //bind table pag event
                module.bindEvents.pagingall();
                //bind add view event
                //module.bindEvents.xxx();
                //bind update view event
                //module.bindEvents.xxx();
                //bind delete view event
                //module.bindEvents.xxx();
            },
            //
            bindEvents : {

                toolbar : function () {
                    $toolbar.find('button').on('click', function () {
                        //$toolbar.slideToggle('slow');
                        $table_section.slideToggle('slow');
                        $view_add.slideToggle('slow');
                    });
                },
                rowedit : function (tr) {
                    var tools = $(tr).find('td:last'),
                        //_edit = tools.find('button:nth-child(1)');
                    _edit = tools.find('button:has(.edit.icon)');
                    _edit.click(function () {
                        var data = obtainRowData(tr);
                        console.info(JSON.stringify(data));
                        var id = $(tr).data('id');
                        $view_update.find('form').form('set values', data);
                        //
                        stuffForm($view_update.find('form'), data);
                        $view_update.find('input[type=hidden][data-name=id]').val(id);
                        $view_update.modal('show');
                    });
                },
                rowdelete : function (tr) {
                    var tools = $(tr).find('td:last'),
                        //_del = tools.find('button:nth-child(2)');
                    _del = tools.find('button:has(.delete.icon)');
                    _del.click(function () {
                        var id = $(tr).data('id');
                        $view_delete.find('input[type=hidden][data-name=id]').val(id);
                        $view_delete.modal('show');
                    });
                },
                rowdbclick : function (tr) {
                    $(tr).on('dblclick', function () {
                        var tools = $(tr).find('td:last'),
                            _edit = tools.find('button:has(.edit.icon)');
                        _edit.click();
                    });
                },
                tablerow : function () {
                    var editable = module.get.setting.editable(),
                        deletable = module.get.setting.deletable();
                    $table.children('tbody').children('tr').each(function (idx, tr) {
                        if(editable) {
                            module.bindEvents.rowedit(tr);
                        }
                        if(deletable) {
                            module.bindEvents.rowdelete(tr);
                        }

                        if(settings.dbClickEditable === true) {
                            module.bindEvents.rowdbclick(tr);
                        }
                    });
                },
                /*tablerow : function () {
                    $table.children('tbody').children('tr').each(function (idx, tr) {
                        //data
                        //var id = $(tr).data('id')//,
                        //data = obtainRowData(tr);
                        //element
                        var tools = $(tr).find('td:last'),
                            _edit = tools.find('button:nth-child(1)'),
                            _del = tools.find('button:nth-child(2)');
                        //events
                        _edit.click(function () {
                            //
                            if(!settings.enableEdit === true)return;
                            var data = obtainRowData(tr);
                            var id = $(tr).data('id');
                            console.info('edit........');
                            console.info(JSON.stringify(data));
                            $view_update.find('form').form('set values', data);
                            $view_update.find('input[type=hidden][data-name=id]').val(id);
                            $view_update.modal('show');
                        });
                        _del.click(function () {
                            if(!settings.enableDelete === true)return;
                            var id = $(tr).data('id');
                            $view_delete.find('input[type=hidden][data-name=id]').val(id);
                            $view_delete.modal('show');
                        });
                        //enable row double click edit event
                        //if(settings.dbClickEditable === true) {
                        //    $(tr).click(function () {
                        //        if(settings.enableEdit === true)
                        //        _edit.click();
                        //    });
                        //}
                    });
                },*/
                paging : function () {
                    //翻页
                    $table.children('tfoot').find('.ui.pagination.menu a:not(.disabled):not(.icon):not(.active)').each(function (idx, a) {
                        $(a).click(function () {
                            console.info('paging do...');
                            var page = module.get.page(),
                                size = module.get.size(),
                                e_page = Number.parseInt($(this).text());

                            page = isNaN(e_page)?page:e_page;
                            //请求数据，刷新表格
                            var result = retriveTable(page, size);
                            console.info('paging do...');
                            console.info(JSON.stringify(result));
                            if(result.status === 'fail') return;//
                            module.refresh(result.data);
                        });
                    });
                    //上一页和下一页绑定事件
                    $table.children('tfoot').find('.ui.pagination.menu a.icon:not(.disabled)').each(function (idx, a) {
                        $(a).click(function () {
                            var page = module.get.page(),
                                size = module.get.size();
                            //判断是上一页还是下一页
                            if($(a).hasClass('left')) {
                                page = page - 1;
                            } else if ($(a).hasClass('right')) {
                                page = page + 1;
                            }
                            //请求数据，刷新表格
                            var result = retriveTable(page, size);
                            if(result.status === 'fail') return;//
                            module.refresh(result.data);
                        });
                    });
                },
                pagingsize : function () {
                    //请求页大小选择器发生变化时
                    $table.children('tfoot').find('.ui.pagination.label select')
                        .off('change.databind')//unbind change events before bind
                        .on('change.databind', function () {
                            var page = module.get.page(),
                                size = module.get.size();
                            //请求数据
                            //刷新表格（刷新body的row和foot的paging）
                            var result = retriveTable(page, size);
                            if(result.status === 'fail') return;//
                            module.refresh(result.data);
                        });
                },
                pagingall : function () {
                    module.bindEvents.paging();
                    module.bindEvents.pagingsize();
                }
            },



            //刷新数据
            // code: 0 ok | 1 fail
            // msg :
            /* data	: {
             *     totalPage : xx,  //总页数
             *     pageSize : xx,  //页大小
             *     total : xx,     //总记录数
             *     page : xx,      //当前页
             *     rows : [..]    //数据行
             * }
             */
            refresh : function (data) {
                console.info('...............................');
                console.log('开始刷新数据............');
                //refresh table body
                var $tbody = $table.children('tbody'),
                    $label_bar = $table.find('.pagination.label'),
                    $menu_bar = $table.find('.pagination.menu'),
                    $page_labels = $label_bar.children('strong'),
                    $page_size_selector = $label_bar.find('select');

                var total = data.total,
                    page = data.page,
                    page_size = data.pageSize,
                    total_page = Math.ceil(total / page_size);

                var editable = module.get.setting.editable(),
                    deletable = module.get.setting.deletable();

                var editItem = editable
                        ? ('<button class="ui mini teal labeled icon button"><i class="edit icon"></i>编辑</button>')
                        : (''),
                    deleItem = deletable
                        ? ('<button class="ui mini right floated red labeled icon button"><i class="delete icon"></i>删除</button>')
                        : ('');


                //clear table rows
                $tbody.empty();
                $.each(data.rows, function (idx_row, row) {
                    var $tr = $('<tr></tr>');
                    //attach key to data id
                    $tr.data('id', row[key]);
                    $tr.attr('data-id', row[key]);
                    console.info(idx_row);
                    //add row no
                    $tr.append('<td>'+((page-1)*page_size + (idx_row+1))+'</td>');
                    //添加单元格数据到每行
                    $.each(columns, function (idx_col, col) {
                        //if(idx_col === 0) return true;//exclude row no column
                        var $td = $('<td></td>'),
                            inner = $.fn.tablebind.component.output.write[col.type](row[col.name]);
                        //set column data name
                        $td.data('name', col.name);
                        $td.attr('data-name', col.name);
                        //set column elements
                        $td.html(inner);
                        $tr.append($td);
                    });
                    //add last column with operation tools
                    /*$tr.append('<td data-name="tools">' +
                        '<div>' +
                        '<button class="ui mini teal labeled icon button"><i class="edit icon"></i>编辑</button>' +
                        '<button class="ui mini right floated red labeled icon button"><i class="delete icon"></i>删除</button>' +
                        '</div>' +
                        '</td>');*/
                    $tr.append('<td data-name="tools">' +
                        '<div>' +
                        editItem +
                        deleItem +
                        '</div>' +
                        '</td>');
                    //be sure table body is clear before append it
                    $tbody.append($tr);
                });
                //rebind row event
                module.bindEvents.tablerow();

                //refresh paging bar
                module.loadPaging($table, total, page, page_size);
                //rebind paging events
                module.bindEvents.paging();


            },
            /**
             * 刷新分页条
             * @param table
             * @param total
             * @param current_page
             * @param page_size
             */
            loadPaging : function loadPaging(table, total, current_page, page_size) {
                var $table = $(table);
                var total_page = Math.ceil(total / page_size);
                var $label_bar = $table.find('.pagination.label'),
                    $menu_bar = $table.find('.pagination.menu'),
                    $page_labels = $label_bar.children('strong'),
                    $page_size_selector = $label_bar.find('select');

                $page_labels.eq(0).text(total);
                $page_labels.eq(1).text(total_page);
                //会导致select发生改变循环请求数据
                //$page_size_selector.dropdown('set selected', page_size);

                //小于等于6页 全部显示
                //大于6页 前5页全部显示，中间省略，最后一页显示
                //当前页小于5
                //第一页显示，省略，中间3页（上一页，当前页，下一页），省略，最后一页
                //当前页大于等于5，但不是最后5页
                //当前页为最后5页
                //第一页，省略，最后5页连续
                //最开始5页
                //前一页，后一页
                var $pre = $('<a class="icon item left"><i class="left chevron icon"></i>上一页</a>'),
                    $next = $('<a class="icon item right">下一页<i class="right chevron icon"></i></a>'),
                    $items = $('<div></div>');
                if(total_page < 7) {
                    //全部显示
                    var start = 0;
                    while (start < total_page) {
                        start ++;
                        if(start === current_page) {
                            $items.append('<a class="item active">'+start+'</a>');
                        }
                        else {
                            $items.append('<a class="item">'+start+'</a>');
                        }
                    }
                } else if(current_page < 5) {
                    //前5页，省略，最后一页
                    var start = 0;
                    while (start < 5) {
                        start ++;
                        if(current_page === start) {
                            $items.append('<a class="item active">'+start+'</a>');
                        } else {
                            $items.append('<a class="item">'+start+'</a>');
                        }
                    }
                    $items.append('<a class="item disabled">...</a>');
                    $items.append('<a class="item">'+total_page+'</a>');

                } else if((total_page - current_page) < 4) {
                    //第一页，省略，后5页
                    $items.append('<a class="item">1</a>');
                    $items.append('<a class="item disabled">...</a>');

                    var start = total_page - 4;
                    while (start <= total_page) {
                        if(start === current_page) {
                            $items.append('<a class="item active">'+start+'</a>');
                        } else {
                            $items.append('<a class="item">'+start+'</a>');
                        }
                        start ++;
                    }
                } else {
                    //第一页，省略，中间3页，省略，最后一页
                    $items.append('<a class="item">1</a>');
                    $items.append('<a class="item disabled">...</a>');
                    $items.append('<a class="item">'+(current_page-1)+'</a>');
                    $items.append('<a class="item active">'+(current_page)+'</a>');
                    $items.append('<a class="item">'+(current_page+1)+'</a>');
                    $items.append('<a class="item disabled">...</a>');
                    $items.append('<a class="item">'+total_page+'</a>');
                }
                //
                if(current_page === 1) {
                    $pre.addClass('disabled');
                }
                if(current_page === total_page) {
                    $next.addClass('disabled')
                }
                $menu_bar.html($pre).append($items.html()).append($next);
            },

            get : {
                //当前页
                page : function () {
                    var $current_item = $table.children('tfoot').find('.pagination.menu a.active'),
                        page = 1;
                    page = ($current_item.length === 0) ? page : $current_item.text();
                    page = Number.parseInt(page);
                    if(isNaN(page)) page = 1;
                    return page;
                },
                //页大小
                size : function () {
                    var $page_size_selector = $table.find('.pagination.label').find('select'),
                        size = 20;
                    size = ($page_size_selector.length === 0) ? size : $page_size_selector.val();
                    size = Number.parseInt(size);
                    if(isNaN(size)) size = 20;
                    return size;
                },
                //列
                column : function (name) {
                    var column;
                    $.each(columns, function (idx, col) {
                        if(name === col.name) {
                            column = col;
                            return false;
                        }
                    });
                    return column;
                },
                tokens : function () {
                    var headers = {};
                    var token = $("meta[name='_csrf']").attr("content"),
                        header = $("meta[name='_csrf_header']").attr("content");
                    headers[header] = token;
                    return headers;
                },
                loader : function () {
                    const info = '操作处理中...';
                    var _info = arguments.length > 0 ? arguments[0] : info;
                    var $dimmer = $('body').children('.ui.page.inverted.dimmer');
                    if($dimmer.length === 0) {
                        $dimmer = $('<div class="ui page inverted dimmer">' +
                            '<div class="content">' +
                            '<div class="center"><div class="ui large text loader"><h2>' +
                            _info +
                            '</h2></div></div>' +
                            '</div></div>');
                        $('body').append($dimmer);
                    }
                    $dimmer.find('.ui.loader h2').text(_info);
                    $dimmer.dimmer({closable : false});

                    return $dimmer;
                },
                setting : {
                    editable : function () {
                        return (settings.enableEdit === true)?true:false;
                    },
                    deletable : function () {
                        return (settings.enableDelete === true)?true:false;
                    }
                }

            }
        };



        function stuffForm(form, data) {
            $(form).find('div.field').each(function (idx, field) {
                console.info($(field).find('input[name]').attr('name'));
                var img = $(field).find('img[data-name]');

                if(img.length === 0) return true;
                var name = img.data('name');
                var col = module.get.column(name);
                if((col === undefined) || !(col.type === 'image')) return true;
                console.info('@@@@@@@@@@@@');
                console.log($(field).find('input[type=hidden]').val());
                img.attr('src', $(field).find('input[type=hidden]').val());
            });
        }
        //查询table id
        function queryTableId(tableId) {
            if(tableId === undefined) {
                return 'data_table_' + $('table').length
            }
            return tableId;
        }

        //检查元素是否符合组件需求
        function checkElements () {
            if($toolbar.length === 0) return false;
            if($table.length === 0) return false;
            if($view_add.length === 0) return false;
            if($view_update.length === 0) return false;
            if($view_delete.length === 0) return false;
            return true;
        }
        //配置检查
        function checkSetting() {
            if(settings.dataUrl === '') {
                //throw new settingException(INVALID_DATA_URL);
                throw INVALID_DATA_URL;
            }
            if(settings.enableAdd && (settings.addUrl === '')) {
                //throw new settingException(INVALID_ADD_URL);
                throw INVALID_ADD_URL;
            }
            if(settings.enableEdit && (settings.updateUrl === '')) {
                //throw new settingException(INVALID_UPDATE_URL);
                throw INVALID_UPDATE_URL;
            }
            if(settings.enableDelete && (settings.deleteUrl === '')) {
                //throw new settingException(INVALID_DELETE_URL);
                throw INVALID_DELETE_URL;
            }
        }
        //配置异常对象
        function settingException(msg) {
            this.message = msg;
            this.name = 'settingException';
        }

        //获取单元行的数据
        function obtainRowData(tr) {
            var row_data = {};
            $(tr).find('td:not(:first):not(:last)').each(function (idx, td) {
                /**
                 var name = $(td).data('name'),
                 column = module.get.column(name),
                 value = $.fn.tablebind.component.output.retrieve[column.type]($(td));
                 row_data[name]=value;
                 */
                var name = $(td).data('name');
                console.info('COL_NAME: '+name);
                var column = module.get.column(name);
                //避免低级错误
                //if(column === undefined) return true;

                var value = $.fn.tablebind.component.output.retrieve[column.type]($(td));
                row_data[name]=value;
            });
            //
            return row_data;
        }
        //创建tool bar
        function createAddItem() {
            var $add = $('<div class="two wide column"><button class="ui green labeled icon button"><i class="add icon"></i>添加</button></div>');
            return $add;
        }
        function createSearchItem() {
            var $search = $('<div class="nine wide column row">' +
                '<div><span>选择列：</span><select class="ui search dropdown"></select></div>' +
                '<div>' +
                '<div class="ui action left icon input"><i class="search icon"></i><input type="text" placeholder="Search...">' +
                '<div class="ui blue button">查询</div></div></div>');
            var options = '';
            $.each(columns, function () {
                options += this.searchable?'<option value="'+this.name+'">'+this.label+'</option>':'';
            });
            $search.find('select').html($search.find('select').html()+options);
            $search.find('.ui.button').click(function () {
                var words = $(this).val();
                $(this).val(words.trim());
                eventAction();
            });
            $search.find('input').on('keyup', function (event) {
                if(event.keyCode === 13) {
                    eventAction();
                }
            });

            var eventAction = function () {
                var data = query($search.find('select').val(), $search.find('input').val());
                if(data.status === 'fail') {
                    console.info(data.data);
                } else if(data.status === 'success') {
                    module.refresh(data.data);
                }
            };
            //返回检索的数据
            var query = function (field, value) {
                var headers = module.get.tokens();
                var result = {status:'fail',data:{}};

                var param_data = {
                    field : field,
                    value : value,
                    page  : module.get.page(),
                    size  : module.get.size()
                } ;
                $.ajax({
                    type : 'GET',
                    url : settings.dataUrl,
                    data : param_data,
                    contentType : "application/json",
                    dataType : 'json',
                    headers : headers,
                    success: function (data){
                        if(data.code === 1) {
                            $.each(data.data, function (id, error) {
                                console.log(id+':'+error);
                            });
                        } else {
                            result.status='success';
                            result.data = data.data;
                        }
                        console.log(data);
                    }
                }).done(function (data) {
                    console.info('done');
                }).fail(function (data) {
                    console.info('fail');
                    result.data = data;
                }).always(function () {
                    console.info('always');
                });

                return $search;
        }

            return $search;
        }

        function createToolBar() {
            var $tool = $('<div class="ui grid segment" data-section="toolBar"></div>'),
                $add = $(''),
                $search = createSearchItem();
            if(settings.enableAdd === true) {
                $add = createAddItem();
            }
            $tool.append($add).append($search);
            //
            return $tool;
        }

        /*
        function createToolBar() {
            var $tool = $('<div class="ui grid segment" data-section="toolBar"></div>'),
                $add = $('<div class="two wide column"><button class="ui green labeled icon button"><i class="add icon"></i>添加</button></div>'),
                $search = $('<div class="nine wide column row">' +
                    '<div><span>选择列：</span><select class="ui search dropdown"></select></div>' +
                    '<div>' +
                    '<div class="ui action left icon input"><i class="search icon"></i><input type="text" placeholder="Search...">' +
                    '<div class="ui blue button">查询</div></div></div>');

            var options = '';
            $.each(columns, function () {
                options += this.searchable?'<option value="'+this.name+'">'+this.label+'</option>':'';
            });
            $search.find('select').html($search.find('select').html()+options);

            $tool.append($add).append($search);
            //bind events
            ////放在所有组件确定完全初始化之后绑定
            //$search.find('button').click(function () {
            //
            //});
            $search.find('.ui.button').click(function () {
                var words = $(this).val();
                $(this).val(words.trim());
                eventAction();
            });
            $search.find('input').on('keyup', function (event) {
                if(event.keyCode === 13) {
                    eventAction();
                }
            });

            var eventAction = function () {
                var data = query($search.find('select').val(), $search.find('input').val());
                if(data.status === 'fail') {
                    console.info(data.data);
                } else if(data.status === 'success') {
                    module.refresh(data.data);
                }
            };
            //返回检索的数据
            var query = function (field, value) {
                var headers = module.get.tokens();
                var result = {status:'fail',data:{}};

                var param_data = {
                    field : field,
                    value : value,
                    page  : module.get.page(),
                    size  : module.get.size()
                } ;
                $.ajax({
                    type : 'GET',
                    url : settings.dataUrl,
                    data : param_data,
                    contentType : "application/json",
                    dataType : 'json',
                    headers : headers,
                    success: function (data){
                        if(data.code === 1) {
                            $.each(data.data, function (id, error) {
                                console.log(id+':'+error);
                            });
                        } else {
                            result.status='success';
                            result.data = data.data;
                        }
                        console.log(data);
                    }
                }).done(function (data) {
                    console.info('done');
                }).fail(function (data) {
                    console.info('fail');
                    result.data = data;
                }).always(function () {
                    console.info('always');
                });
                //
                return result;
            };

            return $tool;
        }
        */
        //创建表头以及分页
        function createTable() {
            var $table = $('<table class="ui small celled striped selectable compact table"><thead><tr></tr></thead><tbody></tbody></table>'),
                $head = $table.children('thead').children('tr');

            $head.append('<th>#</th>');
            $.each(columns, function () {
                $head.append('<th>'+this.label+'</th>');
            });
            $head.append('<th class="three wide">操作</th>');

            console.info('t---head');
            console.info($head);
            console.info($head.html());

            var $foot = createPagingBar();
            $table.append($foot);
            return $table;
        }

        function createPagingBar() {
            var $footer = $('<tfoot><tr></tr></tfoot>');

            $footer.children('tr').append('<th colspan="'+(columns.length+2)+'">' +
                '<div class="ui pagination label floated left">' +
                '<strong>0</strong><span class="section">条</span>' +
                '<strong>0</strong><span class="section">页</span>' +
                '<span>每页：</span>' +
                '<select name="pagesize" class="ui mini dropdown">' +
                '<option value="20" selected="selected">20</option>' +
                '<option value="30">30</option>' +
                '<option value="50">50</option>' +
                '<option value="100">100</option>' +
                '</select>' +
                '<span>条</span>' +
                '</div>' +
                '<div class="ui mini right floated pagination menu "></div></th>');
            return $footer;
        }

        /**
         * 添加到Dom中后务必初始化组件，如初始化calendar，初始化dropdown等
         * @returns {*|HTMLElement}
         */
        function createAddView() {
            var $view = $('<div class="segment" style="display: none;"></div>');
            //$view.data('section', 'add');
            $view.attr('data-section', 'add');

            var $form_container = $('<div class="ui segment"><div class="ui huge header"><i class="add user icon"></i>添加用户</div><div class="content"></div></div>'),
                $form = $('<form class="ui form"></form>');
            $form.append('<div class="ui divider"></div>');
            $.each(columns, function (idx, col) {
                if(!col.writable) return true;
                var $field = $($.fn.tablebind.component.input.write.inline[col.type]);
                $field
                    .append($.fn.tablebind.component.input.write.label['text'](col.label))
                    .append($.fn.tablebind.component.input.write.input[col.type]);
                $.fn.tablebind.component.input.write.name[col.type]($field, col.name);
                if(col.required === true) $field.addClass('required');
                if($.fn.tablebind.component.input.bind[col.type] === undefined);
                else {
                    $.fn.tablebind.component.input.bind[col.type]($field);
                }
                //
                $form.append($field);
            });
            var $actions = $('<div class="actions">' +
                '<div class="ui button">取消</div>' +
                '<div class="ui primary button">保存</div>' +
                '</div>');
            $form.append('<div class="ui divider"></div>').append($actions)
                .append('<div class="ui error message"></div>');
            $form_container.find('.content').append($form);
            $view.append($form_container);

            $actions.children('.ui.button').eq(0).click(function () {
                //
                //$wrapper.children('div[data-section=toolBar]').slideToggle('slow');
                //$wrapper.children('table').slideToggle('slow');
                //
                $table_section.slideToggle('slow');
                $view.slideToggle('slow');
            });

            $actions.children('.ui.button').eq(1).click(function (event) {
                if(settings.addUrl === '') {
                    console.log('请配置正确的创建数据URL');
                    return;
                }
                module.get.loader().dimmer('toggle');
                //$form.addClass('loading');
                //$form.form('validate form');
                //event.setTimeout($form.form('validate form'), 1200);
                //setTimeout($form.form('validate form'), 3200);
                //window.setTimeout($form.form('validate form'), 10000);
            });
            //form validate rules
            var fields = {};
            $.each(columns, function (idx, col) {
                if (!col.writable) return true;
                fields[col.name] = {
                    identifier : col.name,
                    rules : col.validate
                }
            });

            $form.form({
                fields : fields,
                onSuccess : function (event, fields) {
                    var headers = module.get.tokens();
                    //post data
                    $.ajax({
                        type : 'POST',
                        url : settings.addUrl,
                        data : JSON.stringify(fields),
                        contentType : "application/json",
                        dataType : 'json',
                        headers : headers,
                        success: function (data){
                            if(data.code === 1) {
                                $.each(data.data, function (id, error) {
                                    $form.form('add prompt', id);
                                    console.log(error);
                                });
                                $form.form('add errors', data.data);
                            } else {
                                location.reload();
                                settings.onAddSucess($view, $wrapper, table_id);
                            }

                            console.log(data);
                        }
                    }).done(function (data) {
                        console.info('done');
                        module.get.loader().dimmer('toggle');
                    }).fail(function (data) {
                        console.info('fail');
                        settings.onAddFail(data, $view, $wrapper, table_id);
                    }).always(function () {
                        console.info('always');
                    });
                },
                //保留
                onFailure : function (formErrors, fields) {
                    //$form.removeClass('loading');
                    console.log(formErrors);
                    console.log(fields);
                    module.get.loader().dimmer('toggle');
                }

            });

            return $view;
        }

        //创建更新窗口
        function createUpdateView() {
            var $view = $('<div class="ui modal segment"></div>');
            //$view.data('section', 'update');
            //$view.data('id', table_id);
            $view.attr('data-section', 'update');
            $view.attr('data-table', table_id);

            $view.html('<i class="close icon massive"></i><div class="header">编辑</div>');
            var $content = $('<div class="content"><form class="ui form"></form></div>'),
                $actions = $('<div class="actions"><button class="ui button">取消</button>' +
                    '<button class="ui primary button">保存</button></div>'),
                $key = $('<input type="hidden" data-name="id">'),
                $form = $content.children('form');
            $key.data('name', 'id');
            $form.append($key);

            $.each(columns, function (idx, col) {
                if(!col.updatable) return true;
                var $field = $($.fn.tablebind.component.input.write.inline[col.type]);
                $field
                    .append($.fn.tablebind.component.input.write.label['text'](col.label))
                    .append($.fn.tablebind.component.input.write.input[col.type]);
                $.fn.tablebind.component.input.write.name[col.type]($field, col.name);
                if(col.required === true) $field.addClass('required');
                if($.fn.tablebind.component.input.bind[col.type] === undefined);
                else {
                    $.fn.tablebind.component.input.bind[col.type]($field);
                }
                //
                $form.append($field);
            });
            $form.append('<div class="ui error message"></div>');

            $view.append($content);
            $view.append($actions);

            $actions.children('button').eq(0).click(function () {
                $view.modal('hide');
            });
            $actions.children('button').eq(1).click(function () {
                $form.form('validate form');
            });

            //form validate rules
            var fields = {};
            $.each(columns, function (idx, col) {
                if (!col.updatable) return true;
                fields[col.name] = {
                    identifier : col.name,
                    rules : col.validate
                }
            });

            $form.form({
                fields : fields,
                onSuccess : function (event, fields) {
                    var headers = module.get.tokens();
                    //post data
                    $.ajax({
                        type : 'POST',
                        url : settings.updateUrl,
                        data : JSON.stringify(fields),
                        contentType : "application/json",
                        dataType : 'json',
                        headers : headers,
                        success: function (data){
                            if(data.code === 1) {
                                $.each(data.data, function (id, error) {
                                    $form.form('add prompt', id);
                                    console.log(error);
                                });
                                $form.form('add errors', data.data);
                            } else {
                                //location.reload();
                                settings.onModSuccess($view, $wrapper, table_id);
                            }
                            console.log(data);
                        }
                    }).done(function (data) {
                        console.info('done');
                    }).fail(function (data) {
                        console.info('fail');
                        settings.onModFail(data, $view, $wrapper, table_id);
                    }).always(function () {
                        console.info('always');
                    });
                },
                //保留
                onFailure : function (formErrors, fields) {
                    console.log(formErrors);
                    console.log(fields);
                }

            });

            return $view;
        }
        //创建删除窗口
        function createDeleteView() {

            var $view = $('<div class="ui basic modal small"></div>'),
                $header = $('<div class="ui icon header"><i class="warning circle icon red"></i>正在进行危险操作...</div>'),
                $content = $('<div class="content"><i class="info circle icon"></i>确定<span class="red">删除数据</span>?</div>'),
                $hide_key = $('<input type="hidden">'),
                $actions = $('<div class="actions">' +
                    '<div class="ui red ok inverted button"><i class="checkmark icon"></i>是</div>' +
                    '<div class="ui green basic cancel inverted button"><i class="remove icon"></i>否</div>' +
                    '</div>');
            $view.attr('data-section', 'delete');
            $view.attr('data-table', table_id);

            $view.html($header);
            $content.append($hide_key);
            $view.append($content);
            $view.append($actions);
            $actions.children('.cancel').click(function () {
                $view.modal('hide');
            });
            $actions.children('.ok').click(function () {
                module.get.loader('数据删除中...').dimmer('show');
                $view.modal('hide');

                var id = $content.children('input').val(),
                    post_body = {id:id};

                var headers = module.get.tokens();
                //post data
                $.ajax({
                    type : 'POST',
                    url : settings.deleteUrl,
                    data : post_body,
                    contentType : "application/json",
                    dataType : 'json',
                    headers : headers,
                    success: function (data){
                        module.get.loader('操作成功').dimmer('show');
                        //setTimeout(module.get.loader().dimmer('hide'), 1200);
                        if(data.code === 1) {
                            $.each(data.data, function (id, error) {
                                console.log(id+':'+error);
                            });

                        } else {
                            //location.reload();
                            settings.onDelSuccess($view, $wrapper, table_id);
                        }
                        console.log(data);
                    }
                }).done(function (data) {

                    console.info('done');
                }).fail(function (data) {
                    module.get.loader('操作失败！').dimmer('show');
                    //setTimeout(module.get.loader().dimmer('hide'), 1200);

                    //module.get.loader().dimmer('toggle');
                    console.info('fail');
                    //settings.onDelFail(data, $view, $wrapper, table_id);
                }).always(function () {
                    console.info('always');
                });

            });

            return $view;
        }

        //请求数据
        function retriveTable(page, size) {
            module.get.loader('数据加载中...').dimmer('toggle');
            var headers = module.get.tokens();
            var result = {status:'fail',data:{}};
            //get data
            //必须同步
            $.ajax({
                async : false,
                type : 'GET',
                url : settings.dataUrl,
                data : {size:size,page:page},
                dataType : 'json',
                headers : headers,
                success: function (data){
                    if(data.code === 1) {
                        $.each(data.data, function (id, error) {
                            console.log(id+':'+error);
                        });
                    } else {
                        result.status='success';
                        result.data = data.data;
                    }
                    console.log(data);
                }
            }).done(function (data) {
                module.get.loader().dimmer('toggle');
                console.info('done');
            }).fail(function (data) {
                console.info('fail');
                result.data = data;
            }).always(function () {
                console.info('always');
            });

            return result;
        }

        /*
         */
        //init
        module.initialize();
        //
        return (returnedValue !== undefined)
            ? returnedValue
            : this
            ;
    };

    //publish default setting
    $.fn.tablebind.settings = {
        key : "id",
        tableId : undefined,
        dbClickEditable : false,
        table : 'table',
        erorrClass : '',
        editorClass : '',
        changeClass : '',
        //是否启用创建，更新，删除数据
        enableAdd : true,
        enableEdit : true,
        enableDelete : true,
        //加载table的url
        dataUrl : '',
        //添加数据url
        addUrl : '',
        //更新数据url
        updateUrl : '',
        //删除数据url
        deleteUrl : '',
        //搜索url
        //queryUrl : '',和加载data使用同一个URL
        //更新成功后执行函数
        onModSuccess : function ($view, $wrapper, id) {
            //default refresh table
            //modal hide
        },
        onModFail : function (error, $view, $wrapper, id) {

        },
        //创建成功后执行函数
        onAddSucess : function ($view, $wrapper, id) {
            //default refresh table
            //toggle form
        },
        //
        onAddFail : function ($view, $wrapper, id) {
            //show fail cause reason
        },
        //删除成功后执行函数
        onDelSuccess : function ($view, $wrapper, id) {
            //default refresh table
            //modal hide
        },
        onDelFail : function (error, $view, $wrapper, id) {

        },
        lengthList : [20, 30, 50, 100]
    };

    //table components
    $.fn.tablebind.component = {
        output : {
            //向单元格写入数据
            write : {
                text : function (val) {
                    return val;
                },
                password : function (val) {
                    return val;
                },
                image : function (val) {
                    return '<img class="ui mini rounded image" src="'+val+'"></img>';
                },
                date : function (val) {
                    return val;
                },
                datetime : function (val) {
                    return val;
                },
                time : function (val) {
                    return val;
                },
                checkbox : function (val) {
                    var _checkbox = val;
                    if((val === true)||(val === 'on')) {
                        _checkbox = '<img data-value="on" src="/static/img/checkbox_checked.gif"></img>';
                    } else {
                        _checkbox = '<img data-value="off" src="/static/img/checkbox_unchecked.gif"></img>';
                    }
                    return _checkbox;
                },
                select : function (val) {
                    return val;
                },
                number : function (val) {
                },
                email : function (val) {
                },
                textarea : function (val) {
                    return val;
                },
                file : function (val) {
                    return '<a href="'+val+'">文件</a>';
                },
                currency : function (val) {
                    return val;
                }
            },
            //向单元格获取数据值
            retrieve : {
                text : function ($output) {
                    return $output.text();
                },
                password : function ($output) {
                    return $output.text();
                },
                image : function ($output) {
                    return $output.find('img').attr('src');
                },
                date : function ($output) {
                    return $output.text();
                },
                datetime : function ($output) {
                    return $output.text();
                },
                time : function ($output) {
                    return $output.text();
                },
                checkbox : function ($output) {
                    var val = $output.find('img').data('value');
                    return (val === 'on')?true:false;
                },
                select : function ($output) {
                    return $output.text();
                },
                number : function ($output) {
                    //return $output.text();
                },
                email : function ($output) {
                    //return $output.text();
                },
                textarea : function ($output) {
                    return $output.text();
                },
                file : function ($output) {
                    return $output.find('a').attr('href');
                },
                currency : function ($output) {
                    return $output.text();
                }
            }

        },
        input : {
            write : {
                inline : {
                    text : '<div class="inline field"></div>',
                    password : '<div class="inline field"></div>',
                    image : '<div class="inline field"></div>',
                    date : '<div class="ui calendar inline field"></div>',
                    datetime : '<div class="ui calendar inline field"></div>',
                    time : '<div class="ui calendar inline field"></div>',
                    checkbox : '<div class="inline field"></div>',
                    select : '<div class="inline field"></div>',
                    textarea : '<div class="inline field"></div>',
                    file : '<div class="inline field"></div>',
                    currency : '<div class="inline field"></div>',

                },
                input : {
                    text : '<input type="text">',
                    password : '<input type="password">',
                    image : '<input type="file" style="display: none;"><input type="hidden"><img class="ui avatar image" src=""><div class="ui icon button"><i class="upload icon"></i></div>',
                    date : '<div class="ui input left icon"><i class="calendar icon"></i><input type="text"></div>',
                    datetime : '<div class="ui input left icon"><i class="calendar icon"></i><input type="text"></div>',
                    time : '<div class="ui input left icon"><i class="calendar icon"></i><input type="text"></div>',
                    checkbox : '<div class="ui checkbox"><input type="checkbox" class="hidden"></div>',
                    select : '<select class="ui dropdown"></select>',
                    number : '',
                    email : '',
                    textarea : '<textarea rows="4"></textarea>',
                    file : '<input type="file" style="display: none;"><input type="hidden"><div class="ui mini label"></div><div class="ui icon button"><i class="upload icon"></i></div>',
                    currency : '<div class="ui input left icon"><i class="yen icon"></i><input type="text"></div>'
                },
                name : {
                    text : function ($field, name) {
                        $field.find('input').attr('name', name);
                    },
                    password : function ($field, name) {
                        $field.find('input').attr('name', name);
                    },
                    image : function ($field, name) {
                        $field.find('input[type=hidden]').attr('name', name);
                        $field.find('img').attr('data-name', name);
                    },
                    date : function ($field, name) {
                        $field.find('input').attr('name', name);
                    },
                    datetime : function ($field, name) {
                        $field.find('input').attr('name', name);
                    },
                    time : function ($field, name) {
                        $field.find('input').attr('name', name);
                    },
                    checkbox : function ($field, name) {
                        $field.find('input').attr('name', name);
                    },
                    select : function ($field, name) {
                        $field.find('select').attr('name', name);
                    },
                    textarea : function ($field, name) {
                        $field.find('textarea').attr('name', name);
                    },
                    file : function ($field, name) {
                        $field.find('input[type=hidden]').attr('name', name);
                    },
                    currency : function ($field, name) {
                        $field.find('input').attr('name', name);
                    }
                },
                label : {
                    text : function () {
                        var label_text = arguments.length > 0 ? arguments[0] : '';
                        return '<label>'+label_text+'</label>';
                    }
                }
            },
            bind : {
                image : function () {
                    var $ele = arguments.length > 0 ? $(arguments[0]) : $('');
                    $ele.find('div.ui.icon.button').click(function () {
                        $ele.children('input[type=file]').click();
                    });
                    $ele.children('input[type=file]').on('change', function (e) {
                        if(e.target.files && e.target.files[0]) {
                            var file = e.target.files[0];
                            //set img
                            $ele.find('img').attr('src', functions.readFileUrl(file));
                            //$ele.find('input[type=hidden]').val(functions.readFileData(file));
                            var input = $ele.find('input[type=hidden]');
                            functions.readFileData(file, input);
                            //var t = functions.readFileData(file);
                            //console.log(t);
                            //$ele.find('input[type=hidden]').val(t);
                            //console.info($ele.find('input[type=hidden]').val());
                        }
                    });
                },
                file : function () {
                    var $ele = arguments.length > 0 ? $(arguments[0]) : $('');
                    $ele.find('div.ui.icon.button').click(function () {
                        $ele.children('input[type=file]').click();
                    });
                    $ele.children('input[type=file]').on('change', function (e) {
                        if(e.target.files && e.target.files[0]) {
                            var file = e.target.files[0];
                            $ele.find('div.ui.label').text(file.name);//file.size file.type
                            var input = $ele.find('input[type=hidden]');
                            functions.readFileData(file, input);
                        }
                    });
                }
            }
        },

        validate : {

        }
    };

    $.fn.tablebind.columns = [
        {
            label : '#',               //显示标签（用于表头以及表单标签）
            name : 'rowno',                 //字段名（和后台请求保持一致，必须唯一）
            writable : false,                 //是否可写
            updatable : false,                //是否可更新
            enableValidate : false,           //是否启用校验
        }
    ];

    $.fn.tablebind.column = {
        index : 0,
        label : '',               //显示标签（用于表头以及表单标签）
        type : 'text',                     //数据类型（用于构建表格单元格以及表单输入框）
        name : '',                 //字段名（和后台请求保持一致，必须唯一）
        required : false,                 //是否必须（添加/修改校验）
        writable : true,                 //是否可写
        updatable : true,                //是否可更新
        searchable : false,               //是否可搜索
        enableValidate : true,           //是否启用校验
        //validate: function () {return true}    //自定义校验函数
        validate: []    //自定义校验函数
    }

    var functions = {
        isSupportFile : function() {
            if (window.File && window.FileReader && window.FileList && window.Blob) {
                return true;
            }
            return false;
        },
        readFileData : function(file, $e) {
            if(!functions.isSupportFile()) return '';
            var reader = new FileReader(),
            dataURL = '';
            if(!(file instanceof window.File)) {
                return dataURL;
            }
            reader.readAsDataURL(file);
            reader.onload = function (e) {
                var dataSRC = e.target.result,
                    data = dataSRC.replace(/^data:\w+\/\w+;base64,/, '');
                dataURL = data;
                console.log(dataSRC);
                console.log(dataURL);
                $e.val(dataURL);
                //dataURL = reader.result;
            }

            //return dataURL;
        },
        readFileUrl : function (file) {
            var file_url = '';
            if(file instanceof window.File) {
                file_url = URL.createObjectURL(file);
            }
            return file_url;
        }
    };

    var type = [
        "text",
        "checkbox",
        "select",
        "number",
        "currency",
        "email",
        "image",
        "textarea",
        "file",
        "date",
        "time",
        "datetime"
    ];
})(jQuery, window, document);